/***************************************************************************
 *   Copyright (C) 2007 by Gaetano Mendola  *
 *   mendola@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <assert.h>

#include "player.h"
#include "weapon.h"

#include "talents/talent.h"

#include "buffs/buff.h"

#include "events/eventdispatcher.h"
#include "events/buff.h"


Player::Player()
: EventSink(),
  theMainHandWeapon(0),
  theOffHandWeapon(0),
  theTalents(),
  theBuffs(),
  theStats()
{
}

Player::~Player()
{
    TalentList::iterator myIt = theTalents.begin();
    TalentList::const_iterator myItEnd = theTalents.end();

    for ( /*empty*/; myIt != myItEnd; ++myIt ) {
        delete (*myIt);
    }
}

void Player::addTalent(Talents::Talent* aTalent) 
{
    theTalents.push_back(aTalent);
    aTalent->learned(this);
}

void Player::addBuff(Buffs::Buff* aBuff)
{
    //Need to check if the buff being gained is already
    //up, if it's up it has to be refreshed (time reset
    //for example, charges etc)

    BuffList::const_iterator it = theBuffs.begin();
    BuffList::const_iterator it_end = theBuffs.end();

    for (/*void*/; it != it_end; ++it) {
        if ( (*it)->id() == aBuff->id() ) { //The player had already the buff up
            Events::Buff * myEvent = new Events::Buff(Events::Buff::REFRESH, aBuff);
            Events::EventDispatcher::instance().notify(myEvent);

            (*it)->refresh();

            delete aBuff;
            return;
        }
    }

    Events::Buff * myEvent = new Events::Buff(Events::Buff::GAIN, aBuff);
    Events::EventDispatcher::instance().notify(myEvent);

    aBuff->gainedFrom(this);
    theBuffs.push_back(aBuff);
}

void Player::removeBuff(Buffs::Buff* aBuff)
{
    BuffList::const_iterator it = theBuffs.begin();
    BuffList::const_iterator it_end = theBuffs.end();

    for (/*void*/; it != it_end; ++it) {
        if ( *it == aBuff ) { //Found the buff to remove
            Events::Buff * myEvent = new Events::Buff(Events::Buff::LOSE, aBuff);
            Events::EventDispatcher::instance().notify(myEvent);

            aBuff->lost();
            theBuffs.remove(aBuff);
            break;
        }
    }

}

bool Player::buffActive(Buffs::Buff::Id anId) const
{
    BuffList::const_iterator it = theBuffs.begin();
    BuffList::const_iterator it_end = theBuffs.end();

    for (/*void*/; it != it_end; ++it) {
        if ( (*it)->id() == anId ) {
            return true;
        }
    }

    return false;
}

void Player::addStat(Stats::Stat* aStat)
{
    theStats.push_back(aStat);
}

void Player::equipInMainHand(Weapon* aWeapon)
{
    delete theMainHandWeapon;
    theMainHandWeapon = aWeapon;
    aWeapon->equiped(this);
}

void Player::equipInOffHand(Weapon* aWeapon)
{
    delete theOffHandWeapon;
    theOffHandWeapon = aWeapon;
    aWeapon->equiped(this);
}

